﻿using System.IO;
using System.Xml;
using System;
using System.Xml.Serialization;

namespace SaveMachine
{
    public class SaveManager
    {
        public string autosaveNotation;
        public int autosaveTimer;
        public int autosaveFreq;

        public string lastSaveName;
        public dynamic lastSaveContent;

        public System.Collections.Generic.List<Type> saveTypes;

        /// <summary>
        /// Constructs a new instance of SaveService.
        /// You will need to define some type as ISaveable which is the type that
        /// will be saved and loaded. Note that this type may be of any type,
        /// including lists and other adt:s.
        /// In order to use the autosave feature you will need to
        /// call the Autosaver function regularly (eg once/frame).
        /// </summary>
        /// <param name="autosaveNotation">The name notation for autosaves, eg "_autosave".</param>
        /// <param name="autosaveFreq">How frequently it should autosave,
        /// in whatever timeframe you use.</param>
        public SaveManager(string autosaveNotation, int autosaveFreq)
        {
            this.autosaveNotation = autosaveNotation;
            this.autosaveFreq = autosaveFreq;
            autosaveTimer = 0;
            saveTypes = new System.Collections.Generic.List<Type>();
        }

        /// <summary>
        /// Updates the autosave timer. Returns true if it autosaves, otherwise false.
        /// </summary>
        /// <param name="elapsedTime">How much time has passed since the last call.</param>
        /// <returns>True if it autosaves, otherwise false.</returns>
        public bool Autosaver(int elapsedTime)
        {
            autosaveTimer += elapsedTime;
            if (autosaveTimer >= autosaveFreq)
            {
                autosaveTimer = 0;
                string origSaveName = lastSaveName;
                Save(lastSaveName + autosaveNotation, lastSaveContent);
                lastSaveName = origSaveName;
                return true;
            }
            return false;
        }

        public void Save<T>()
        {
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            XmlWriter xWrite = XmlWriter.Create(lastSaveName, settings);
            new XmlSerializer(typeof(T), saveTypes.ToArray()).Serialize(xWrite, lastSaveContent);
            xWrite.Close();
#if XBOX
            //TEMP Testing storage
            //StorageContainer container = Vattenspelet.device.OpenContainer("Vattenspelet");
            //string fileName = Path.Combine(container.Path, saveFlagName);

            //FileStream stream = File.Open(fileName, FileMode.Create);

            //XmlSerializer serializer = new XmlSerializer(typeof(Dictionary<string,byte>));
            //serializer.Serialize(stream, ScriptHandler.flags);

            //stream.Close();

            //container.Dispose();
#endif
        }

        public void Save<T>(string saveName, T saveContent)
        {
            lastSaveName = saveName;
            lastSaveContent = saveContent;
            Save<T>();
        }

        public bool Load<T>(out T saveContent)
        {
            if (File.Exists(lastSaveName))
            {
                XmlReader xRead = XmlReader.Create(lastSaveName);
                saveContent = (T)new XmlSerializer(typeof(T), saveTypes.ToArray()).Deserialize(xRead);
#if XBOX
                //SOLVE XBOX HERE
#endif
                xRead.Close();
                return true;
            }
            else
            {
                saveContent = default(T);
                return false;
            }
        }
        public bool Load<T>(out T saveContent, string saveName)
        {
            lastSaveName = saveName;
            return Load<T>(out saveContent);
        }
    }
}
